package com.glink.manage.service.Impl;

import cn.hutool.core.date.LocalDateTimeUtil;
import com.glink.common.contants.BaseCodeConstants;
import com.glink.common.exception.GeneralSimpleException;
import com.glink.manage.domain.*;
import com.glink.manage.dto.view.ConstructionStatusDTO;
import com.glink.manage.dto.view.SitePersonPageDTO;
import com.glink.manage.dto.view.SiteWeatherDTO;
import com.glink.manage.service.*;
import com.glink.manage.vo.attendance.AttendanceProjectStatisticsVO;
import com.glink.manage.vo.view.*;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author lumm
 * @since 2025-01-21
 */
@Service
@Slf4j
public class InformationOverviewServiceImpl implements InformationOverviewService {

    @Autowired
    private OrgService orgService;

    @Autowired
    private ConstructionWorkSiteService constructionWorkSiteService;

    @Autowired
    private ParticipatingUnitService participatingUnitService;

    @Autowired
    private ConstructionWorkService constructionWorkService;

    @Autowired
    private AttendanceService attendanceService;

    @Autowired
    private PersonManageService personManageService;

    @Autowired
    private PersonTrainingRecordService personTrainingRecordService;

    @Autowired
    private PersonCertService personCertService;

    @Autowired
    private UserService userService;

    @Autowired
    private SilentResultService silentResultService;
    
    @Autowired
    private VehicleService vehicleService;
    
    @Autowired
    private VehicleTransitRecordService vehicleTransitRecordService;
    
    /**
     * 根据施工现场ID查询参建单位的人员今日出勤、培训合格、特种作业信息
     *
     * @param dto 施工现场ID
     * @return 参建单位的人员今日出勤、培训合格、特种作业信息
     */
    @Override
    public List<ParticipatingUnitVO> queryOnSitePagePersonnelById(SitePersonPageDTO dto) throws GeneralSimpleException {
        List<ParticipatingUnitVO> participatingUnitVOList = new ArrayList<>();

        //筛选今日出勤的人数
        LocalDate today = LocalDate.now();
        List<AttendanceBean> attendanceBeanList = attendanceService.lambdaQuery()
                .eq(AttendanceBean::getConstructionWorkSiteObjId, dto.getConstructionWorkSiteObjId())
                .eq(AttendanceBean::getCheckinDate, today)
                .list();
        if(CollectionUtils.isEmpty(attendanceBeanList)){
            return participatingUnitVOList;
        }

        List<String> unitIdList = attendanceBeanList.stream().map(AttendanceBean::getUnitObjId).distinct().collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(unitIdList)){
            if (CollectionUtils.isNotEmpty(unitIdList)) {

                //3.未删除且非黑名单的参建单位
                List<ParticipatingUnitBean> participatingUnitBeanList = participatingUnitService.lambdaQuery()
                        .in(ParticipatingUnitBean::getObjId, unitIdList)
                        .list();

                if (CollectionUtils.isNotEmpty(participatingUnitBeanList)) {
                    //查询当前参建单位的今日出勤人数
                    participatingUnitBeanList.forEach(participatingUnitBean -> {
                        ParticipatingUnitVO participatingUnitVO = new ParticipatingUnitVO();
                        participatingUnitVO.setUnitId(participatingUnitBean.getObjId());
                        participatingUnitVO.setUnitName(participatingUnitBean.getUnitName());
                        participatingUnitVO.setUnitAbbreviation(participatingUnitBean.getUnitAbbreviation());

                        int todayCheckInCount = 0;
                        int trainingQualified = 0;
                        int specialWorkCount = 0;
                        participatingUnitVO.setTrainingQualifiedCount(trainingQualified);
                        participatingUnitVO.setAttendanceCount(todayCheckInCount);
                        participatingUnitVO.setSpecialWorkCount(specialWorkCount);

                        // 过滤当前单位
                        List<AttendanceBean> unitAttendanceBeanList = attendanceBeanList.stream().filter(obj -> StringUtils.equals(obj.getUnitObjId(), participatingUnitBean.getObjId())).collect(Collectors.toList());

                        if (CollectionUtils.isNotEmpty(unitAttendanceBeanList)) {
                            // 查询有多少人打卡
                            List<String> cardList = unitAttendanceBeanList.stream().map(AttendanceBean::getCard).filter(StringUtils::isNotEmpty).distinct().collect(Collectors.toList());
                            if(CollectionUtils.isNotEmpty(cardList)){
                                // 出勤人数
                                todayCheckInCount = cardList.size();

                                List<PersonManageBean> personManageBeanList = personManageService.lambdaQuery()
                                        .in(PersonManageBean::getCard, cardList).list();
                                if(CollectionUtils.isNotEmpty(personManageBeanList)){
                                    List<String> personIdList = personManageBeanList.stream().map(PersonManageBean::getObjId).collect(Collectors.toList());

                                    //培训合格人数（只要有培训记录，就算合格）
                                    List<PersonTrainingRecordBean> personTrainingRecordBeanList = personTrainingRecordService.lambdaQuery()
                                            .in(PersonTrainingRecordBean::getPersonObjId, personIdList)
                                            .isNotNull(PersonTrainingRecordBean::getContent).ne(PersonTrainingRecordBean::getContent, "")
                                            .list();
                                    if(CollectionUtils.isNotEmpty(personTrainingRecordBeanList)){
                                        // 培训合格
                                        trainingQualified = (int) personTrainingRecordBeanList.stream().map(PersonTrainingRecordBean::getPersonObjId).distinct().count();
                                    }

                                    //特种作业人数（只要有特种作业的资质，就算特种作业）
                                    List<PersonCertBean> personCertBeanList = personCertService.lambdaQuery()
                                            .in(PersonCertBean::getPersonObjId, personIdList)
                                            .eq(PersonCertBean::getIfEnable, BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode01)
                                            .list();
                                    if (CollectionUtils.isNotEmpty(personCertBeanList)) {
                                        // 特种作业
                                        specialWorkCount = (int) personCertBeanList.stream().map(PersonCertBean::getPersonObjId).distinct().count();
                                    }
                                }
                            }

                            participatingUnitVO.setTrainingQualifiedCount(trainingQualified);
                            participatingUnitVO.setAttendanceCount(todayCheckInCount);
                            participatingUnitVO.setSpecialWorkCount(specialWorkCount);
                        }
                        participatingUnitVOList.add(participatingUnitVO);
                    });
                }
            }
        }
        return participatingUnitVOList;
    }

    /**
     * 根据施工现场ID查询车辆出入信息
     *
     * @param dto 施工现场ID
     * @return 根据施工现场ID查询车辆出入信息
     */
    @Override
    public VehicleAccessInfoVO queryVehicleAccessInfoById(SitePersonPageDTO dto) throws GeneralSimpleException {
        VehicleAccessInfoVO vehicleAccessInfoVO = new VehicleAccessInfoVO();
        if(StringUtils.isNotBlank(dto.getConstructionWorkSiteObjId())){

            Set<String> licensePlateList = Sets.newHashSet();
            
            LocalDateTime date = LocalDateTime.now();
            LocalDateTime startTime = LocalDateTimeUtil.beginOfDay(date);
            LocalDateTime endTime = LocalDateTimeUtil.endOfDay(date);
            List<VehicleTransitRecordBean> recordBeanList = vehicleTransitRecordService.lambdaQuery()
                    .eq(VehicleTransitRecordBean::getConstructionWorkSiteObjId, dto.getConstructionWorkSiteObjId())
                    .between(VehicleTransitRecordBean::getLocalTime, startTime, endTime)
                    .orderByDesc(VehicleTransitRecordBean::getLocalTime)
                    .orderByDesc(VehicleTransitRecordBean::getObjId)
                    .list();
            if(CollectionUtils.isNotEmpty(recordBeanList)){
                List<VehicleAccessDetailVO> driveInRecord = Lists.newArrayList();
                recordBeanList.forEach(vehicleTransitRecordBean -> {
                    VehicleAccessDetailVO vehicleAccessDetailVO = new VehicleAccessDetailVO();
                    vehicleAccessDetailVO.setType(vehicleTransitRecordBean.getType());
                    vehicleAccessDetailVO.setCarInout(vehicleTransitRecordBean.getCarInout());
                    vehicleAccessDetailVO.setLicensePlate(vehicleTransitRecordBean.getLicensePlate());
                    vehicleAccessDetailVO.setRecordDate(vehicleTransitRecordBean.getLocalTime());
                    licensePlateList.add(vehicleTransitRecordBean.getLicensePlate());
                    driveInRecord.add(vehicleAccessDetailVO);
                });
                vehicleAccessInfoVO.setDriveInRecord(driveInRecord);
            }

            if(CollectionUtils.isNotEmpty(licensePlateList)){
                // 车辆数量
                Integer carCount = vehicleService.countByTypeAndLicensePlateIn(BaseCodeConstants.CodeType_CarType.KEY_CarType01, licensePlateList);
                vehicleAccessInfoVO.setVehicleCount(carCount);
                // 特种机械数量
                Integer specialEquipCount = vehicleService.countByTypeAndLicensePlateIn(BaseCodeConstants.CodeType_CarType.KEY_CarType02, licensePlateList);
                vehicleAccessInfoVO.setSpecialEquipCount(specialEquipCount);
            }
        }
        
        return vehicleAccessInfoVO;
    }


    /**
     * 查询当前用户组织权限下的工程概况信息
     *
     * @return 工程概况信息
     */
    @Override
    public List<ConstructionWorkInfoVO> queryProjectInfo() throws GeneralSimpleException {
        List<ConstructionWorkInfoVO> constructionWorkInfoVOList = new ArrayList<>();
        //查询是否具有总部管理员角色
        boolean headOffice = userService.checkHeadOffice();
        List<String> orgIdList = null;
        if (!headOffice) {
            orgIdList = orgService.getDataPermissionOrgId();
            if(CollectionUtils.isEmpty(orgIdList)){
                return Lists.newArrayList();
            }
        }
        List<ConstructionWorkBean> constructionWorkBeanList =
                constructionWorkService.lambdaQuery()
                        .in(!headOffice, ConstructionWorkBean::getProjectDepartmentObjId, orgIdList)
                        .list();
        HashMap<String, Integer> constructionProfileInfoMap = new HashMap<>();
        constructionProfileInfoMap.put("在建工程数",0);

        //在建工程数
        long count = constructionWorkBeanList.stream()
                .filter(constructionWorkBean -> BaseCodeConstants.CodeType_ConstructionStatus.KEY_ConstructionStatus01.equals(constructionWorkBean.getStatus()))
                .count();
        constructionProfileInfoMap.put("在建工程数",(int)count);
        constructionProfileInfoMap.forEach((key, value) -> {
            ConstructionWorkInfoVO constructionWorkInfoVO1 = new ConstructionWorkInfoVO();
            constructionWorkInfoVO1.setUseMode(key);
            constructionWorkInfoVO1.setAllQty(value);
            constructionWorkInfoVOList.add(constructionWorkInfoVO1);
        });
        return constructionWorkInfoVOList;
    }

    /**
     * 查询当前用户组织权限下的工程列表信息
     *
     * @return 工程列表信息
     */
    @Override
    public List<ConstructionWorkListVO> queryProjectList( ConstructionStatusDTO dto) throws GeneralSimpleException {
        List<ConstructionWorkListVO> constructionWorkListVOList = new ArrayList<>();
        //查询是否具有总部管理员角色
        boolean headOffice = userService.checkHeadOffice();
        List<String> orgIdList = null;
        List<String> workIdList = null;
        boolean generalContractingUnit = false;
        if (!headOffice) {
            generalContractingUnit = userService.checkGeneralContractingUnit();
            if(generalContractingUnit){
                workIdList = constructionWorkService.findGeneralContractingUnitAccessWorkId();    
                if(CollectionUtils.isEmpty(workIdList)){
                    return Lists.newArrayList();
                }
            }else{
                orgIdList = orgService.getDataPermissionOrgId();
                if(CollectionUtils.isEmpty(orgIdList)){
                    return Lists.newArrayList();
                }    
            }
        }
        List<ConstructionWorkBean> constructionWorkBeanList = constructionWorkService.lambdaQuery()
                .in(!headOffice && !generalContractingUnit, ConstructionWorkBean::getProjectDepartmentObjId, orgIdList)
                .in(!headOffice && generalContractingUnit, ConstructionWorkBean::getObjId, workIdList)
                .eq(StringUtils.isNotBlank(dto.getStatus()),ConstructionWorkBean::getStatus,dto.getStatus())
                .list();
        if (CollectionUtils.isNotEmpty(constructionWorkBeanList)) {
            constructionWorkBeanList.forEach(
                    constructionWorkBean -> {
                        ConstructionWorkListVO constructionWorkListVO = new ConstructionWorkListVO();
                        BeanUtils.copyProperties(constructionWorkBean, constructionWorkListVO);
                        constructionWorkListVOList.add(constructionWorkListVO);
                    }
            );
        }
        return constructionWorkListVOList;
    }

    /**
     * 查询考勤统计信息
     *
     * @return 考勤统计信息
     */
    @Override
    public List<AttendanceProjectStatisticsVO> queryAttendanceTally() throws GeneralSimpleException {
        //查询当天的总人数
        List<String> allDepartmentId = orgService.getDataPermissionDepartmentOrgId();
        if(CollectionUtils.isNotEmpty(allDepartmentId)){
            List<String> workIdList = constructionWorkService.findIdByProjectDepartmentObjIdIn(allDepartmentId);
            if(CollectionUtils.isNotEmpty(workIdList)){
                return attendanceService.projectStatisticsByDateAndWorkIdIn(workIdList);
            }
        }
        return Collections.emptyList();
    }

    /**
     * 查询当日告警信息
     *
     * @return 查询当日告警信息
     */
    @Override
    public List<AlarmInfoVO> queryAlarmInfoToday() throws GeneralSimpleException {

        boolean headOffice = userService.checkHeadOffice();
        List<String> workIdList = Lists.newArrayList();
        if(!headOffice){
            List<String> orgIdList = orgService.getDataPermissionDepartmentOrgId();
            if(CollectionUtils.isNotEmpty(orgIdList)){
                workIdList = constructionWorkService.findIdByProjectDepartmentObjIdIn(orgIdList);
            }
            
            if(CollectionUtils.isEmpty(workIdList)){
                return Lists.newArrayList();
            }
        }

        LocalDateTime today = LocalDateTimeUtil.now();
        LocalDateTime startDateTime = LocalDateTimeUtil.beginOfDay(today);
        LocalDateTime endDateTime = LocalDateTimeUtil.endOfDay(today);
        
        
        return silentResultService.countAlarmInfoTodayByWorkIdInAndHandleTimeBetween(workIdList, startDateTime, endDateTime);
    }

//    @Override
//    public List<AlarmInfoListVO> queryAlarmInfoByWorkId(String workId) throws GeneralSimpleException {
//        List<AlarmInfoListVO> alarmInfoListVOList= Lists.newArrayList();
//        List<SilentResultBean> silentResultBeanList = silentResultService.lambdaQuery()
//                .eq(StringUtils.isNotBlank(workId), SilentResultBean::getConstructionWorkObjId, workId)
//                .eq(SilentResultBean::getIfWarn,"1")
//                .list();
//        if (CollectionUtils.isNotEmpty(silentResultBeanList)) {
//            silentResultBeanList.forEach(
//                    silentResultBean -> {
//                        List<SilentResultDetailBean> silentResultDetailBeanList = silentResultDetailService.lambdaQuery()
//                                .eq(SilentResultDetailBean::getResultObjId, silentResultBean.getObjId()).list();
//                        silentResultDetailBeanList.forEach(
//                                silentResultDetailBean -> {
//                                    AlarmInfoListVO alarmInfoListVO = new AlarmInfoListVO();
//                                    BeanUtils.copyProperties(silentResultBean, alarmInfoListVO);
//                                    ConstructionWorkSiteBean constructionWorkSiteBean = constructionWorkSiteService.getById(silentResultBean.getConstructionWorkSiteObjId());
//                                    if (constructionWorkSiteBean != null) {
//                                        alarmInfoListVO.setConstructionWorkSiteName(constructionWorkSiteBean.getSiteName());
//                                    }
//                                    alarmInfoListVO.setAlarmContent(silentResultDetailBean.getViolationContent());
//                                    alarmInfoListVO.setAlarmTime(silentResultDetailBean.getCreateTime());
//                                    alarmInfoListVOList.add(alarmInfoListVO);
//                                }
//                        );
//                    }
//            );
//        }
//        return alarmInfoListVOList;
//    }

    /**
     * 查询天气
     *
     * @param dto 查询条件
     * @return 天气信息
     */
    @Override
    public SiteWeatherVO queryWeather(SiteWeatherDTO dto) {
        return constructionWorkSiteService.queryWeatherBySiteId(dto.getConstructionWorkSiteObjId());
    }
}